package com.teamblueplus.comicmaker;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Paint;

import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.util.Log;

import android.view.MotionEvent;
import android.view.View;

import android.widget.Toast;

import com.teamblueplus.crop.CropImage;
import com.teamblueplus.imagecrop.CropOption;
import com.teamblueplus.imagecrop.CropOptionAdapter;
import com.teamblueplus.websearch.GoogleSearchAPIActivity;
import com.teamblueplus.R;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import android.content.ActivityNotFoundException;
import android.database.Cursor;

/**
 * This class handles the Image Editor window. It creates the ImageCropActivity
 * and PaintBrush class and display it to the window
 * 
 * @author qui
 * 
 */
public class ImageEditorMakingActivity extends Activity implements
		View.OnTouchListener {

	private ImageEditorSurfaceView ComicSurfaceView;

	private int locX, locY, boundlocX, boundlocY;
	private int isBrushOn;

	private boolean rotate;
	private Bitmap cropBitmap;

	static private File APP_FILE_PATH;
	static private ExportBitmapToFile saveFile;

	private static final int FROM_CROP = 7;

	private final static int SELECT_GALLERY = 1, SELECT_DEFAULT = 2,
			SELECT_CAMERA = 3, SELECT_WEB = 4, EDITOR_GALLERY = 5,
			EDITOR_DEFAULT = 6;

	// path of image taken from camera
	private Uri mImageCaptureUri;
	private String selectedImagePath;

	private boolean isDefault = false;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.image_editormaking);

		ComicSurfaceView = (ImageEditorSurfaceView) findViewById(R.id.comicSurfaceView);
		ComicSurfaceView.setOnTouchListener(this);

		File sdCard = Environment.getExternalStorageDirectory();
		APP_FILE_PATH = new File(sdCard.getAbsolutePath() + "/dimages");

		// brush is disable at first
		isBrushOn = 0;

		int mode = this.getIntent().getExtras().getInt("mode");
		this.checkMode(mode);

	}

	private void checkMode(int mode) {

		if (mode == SELECT_DEFAULT) {
			isDefault = true;
			Intent intent = new Intent(ImageEditorMakingActivity.this,
					AddDefaultObject.class);
			ImageEditorMakingActivity.this.startActivityForResult(intent,
					SELECT_DEFAULT);

		} else if (mode == SELECT_GALLERY) {
			Intent intent = new Intent();
			intent.setType("image/*");
			intent.setAction(Intent.ACTION_GET_CONTENT);
			startActivityForResult(
					Intent.createChooser(intent, "Select Picture"),
					SELECT_GALLERY);

		} else if (mode == SELECT_WEB) {
			Intent intent = new Intent(ImageEditorMakingActivity.this,
					GoogleSearchAPIActivity.class);
			ImageEditorMakingActivity.this.startActivityForResult(intent,
					SELECT_WEB);

		} else if (mode == SELECT_CAMERA) {
			Intent intent = new Intent(
					android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

			mImageCaptureUri = Uri.fromFile(new File(Environment
					.getExternalStorageDirectory(), "tmp_avatar_"
					+ String.valueOf(System.currentTimeMillis()) + ".jpg"));

			intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
					mImageCaptureUri);

			try {
				intent.putExtra("return-data", true);

				startActivityForResult(intent, SELECT_CAMERA);
			} catch (ActivityNotFoundException e) {
				e.printStackTrace();
			}
		}
	}

	private Paint getPreviewPaint() {
		final Paint previewPaint = new Paint();
		previewPaint.setColor(0xFFFFFF00);
		previewPaint.setStyle(Paint.Style.STROKE);
		previewPaint.setStrokeJoin(Paint.Join.ROUND);
		previewPaint.setStrokeCap(Paint.Cap.ROUND);
		previewPaint.setStrokeWidth(3);
		return previewPaint;
	}

	// check if gesture is within the boundaries of the white page
	public void checkBoundaries(MotionEvent motionEvent) {
		locX = (int) motionEvent.getX();
		locY = (int) motionEvent.getY();

		if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
			// gesture is inside the page
			if (locX > 0 && locX < ComicSurfaceView.getPageWidth()
					&& locY > ComicSurfaceView.getTopPadding()
					&& locY < ComicSurfaceView.getPageHeight()) {
				boundlocX = locX;
				boundlocY = locY;

			}
			// gesture started left border
			else if (locX < 0 && locY < ComicSurfaceView.getPageHeight()
					&& locY > ComicSurfaceView.getTopPadding()) {
				boundlocX = 0;
				boundlocY = locY;

			}
			// gesture started at left top corner
			else if (locX < 0 && locY < ComicSurfaceView.getTopPadding()) {
				boundlocX = 0;
				boundlocY = 0;

			}
			// gesture started is at left bottom corner
			else if (locX < 0 && locY > ComicSurfaceView.getPageHeight()) {
				boundlocX = 0;
				boundlocY = ComicSurfaceView.getPageHeight();

			}
			// gesture started at top border
			else if (locY < 0 && locX < ComicSurfaceView.getPageWidth()
					&& locX > 0) {
				boundlocX = locX;
				boundlocY = 0;

			}
			// gesture started at right border
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY < ComicSurfaceView.getPageHeight()
					&& locY > ComicSurfaceView.getTopPadding()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = locY;

			}
			// gesture started at right top corner
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY < ComicSurfaceView.getTopPadding()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = 0;

			}
			// gesture started atright bottom corner
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY > ComicSurfaceView.getPageHeight()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = ComicSurfaceView.getPageHeight();

			}
			// gesture started at bottom
			else if (locY > ComicSurfaceView.getPageHeight()
					&& locX < ComicSurfaceView.getPageWidth() && locX > 0) {
				boundlocX = locX;
				boundlocY = ComicSurfaceView.getPageHeight();

			}

		} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {

			if (locX > 0 && locX < ComicSurfaceView.getPageWidth() && locY > 0
					&& locY < ComicSurfaceView.getPageHeight()) {
				boundlocX = locX;
				boundlocY = locY;

			}

		} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
			// gesture is inside the page
			if (locX > 0 && locX < ComicSurfaceView.getPageWidth()
					&& locY > ComicSurfaceView.getTopPadding()
					&& locY < ComicSurfaceView.getPageHeight()) {
				boundlocX = locX;
				boundlocY = locY;

			}
			// gesture started left border
			else if (locX < 0 && locY < ComicSurfaceView.getPageHeight()
					&& locY > ComicSurfaceView.getTopPadding()) {
				boundlocX = 0;
				boundlocY = locY;

			}
			// gesture started at left top corner
			else if (locX < 0 && locY < ComicSurfaceView.getTopPadding()) {
				boundlocX = 0;
				boundlocY = 0;

			}
			// gesture started is at left bottom corner
			else if (locX < 0 && locY > ComicSurfaceView.getPageHeight()) {
				boundlocX = 0;
				boundlocY = ComicSurfaceView.getPageHeight();

			}
			// gesture started at top border
			else if (locY < ComicSurfaceView.getTopPadding()
					&& locX < ComicSurfaceView.getPageWidth() && locX > 0) {
				boundlocX = locX;
				boundlocY = 0;

			}
			// gesture started at right border
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY < ComicSurfaceView.getPageHeight()
					&& locY > ComicSurfaceView.getTopPadding()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = locY;

			}
			// gesture started at right top corner
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY < ComicSurfaceView.getTopPadding()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = 0;

			}
			// gesture started atright bottom corner
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY > ComicSurfaceView.getPageHeight()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = ComicSurfaceView.getPageHeight();

			}
			// gesture started at bottom
			else if (locY > ComicSurfaceView.getPageHeight()
					&& locX < ComicSurfaceView.getPageWidth() && locX > 0) {
				boundlocX = locX;
				boundlocY = ComicSurfaceView.getPageHeight();

			}
		}

	}

	public void paintBrush2(MotionEvent motionEvent) {

		if (this.isBrushOn == 1) {
			int x = (int) motionEvent.getX();
			int y = (int) motionEvent.getY();

			if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
				this.ComicSurfaceView.brush2.touch_start(x, y);

			} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
				this.ComicSurfaceView.brush2.touch_move(x, y);

			} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
				this.ComicSurfaceView.brush2.touch_up();

			}
		}

	}

	@Override
	public boolean onTouch(View view, MotionEvent motionEvent) {

		// check if paint brush is on
		this.paintBrush2(motionEvent);

		if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {

		} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {

		} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {

		}

		return true;
	}

	public void onClick(View view) {
		switch (view.getId()) {
		case R.id.okBtn:
			// save the edited bitmap to file

			this.ComicSurfaceView.isDrawing = false;
			Handler saveHandler = new Handler() {
				@Override
				public void handleMessage(Message msg) {
					setResult(RESULT_OK);
					saveFile = null;
					Intent intent = new Intent();
					intent.putExtra("path", selectedImagePath);
					setResult(RESULT_OK, intent);

					finish();
				}
			};

			saveFile = new ExportBitmapToFile(this, saveHandler,
					ComicSurfaceView.getBitmap(), selectedImagePath);
			saveFile.execute();

			break;

		case R.id.cancelBtn:
			// kill activity
			finish();

			break;

		case R.id.cropBtn:
			Intent intent = new Intent(this, CropImage.class);
			intent.putExtra("image-path", this.selectedImagePath);
			intent.putExtra("scale", true);
			intent.putExtra("return-data", true);
			startActivityForResult(intent, FROM_CROP);
			// doCrop();
			break;
		}
	}

	private void doCrop() {
		final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
		Log.d("h2", "doCrop()");
		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setType("image/*");

		// check how many croppipng app are installed
		List<ResolveInfo> list = getPackageManager().queryIntentActivities(
				intent, 0);

		int size = list.size();

		if (size == 0) {
			Toast.makeText(this, "Can not find image crop app",
					Toast.LENGTH_SHORT).show();

			return;
		} else {

			intent.setData(Uri.fromFile(new File(this.selectedImagePath)));

			// intent.putExtra("outputX", 300);
			// intent.putExtra("outputY", 300);
			intent.putExtra("aspectX", 1);
			intent.putExtra("aspectY", 1);
			intent.putExtra("scale", true);
			intent.putExtra("return-data", true);

			// uses the phone crop feature
			if (size == 1) {
				Log.d("h2", "11111");
				Intent i = new Intent(intent);
				ResolveInfo res = list.get(0);

				i.setComponent(new ComponentName(res.activityInfo.packageName,
						res.activityInfo.name));

				startActivityForResult(i, FROM_CROP);
			}
			// ask the user to choose which crop app to use, either the default
			// or custom one
			else {
				Log.d("h2", "22222");

				for (ResolveInfo res : list) {
					final CropOption co = new CropOption();

					co.title = getPackageManager().getApplicationLabel(
							res.activityInfo.applicationInfo);
					co.icon = getPackageManager().getApplicationIcon(
							res.activityInfo.applicationInfo);
					co.appIntent = new Intent(intent);

					co.appIntent
							.setComponent(new ComponentName(
									res.activityInfo.packageName,
									res.activityInfo.name));

					cropOptions.add(co);
				}

				CropOptionAdapter adapter = new CropOptionAdapter(
						getApplicationContext(), cropOptions);

				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setTitle("Choose Crop App");
				builder.setAdapter(adapter,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int item) {
								startActivityForResult(
										cropOptions.get(item).appIntent,
										FROM_CROP);
							}
						});

				builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
					@Override
					public void onCancel(DialogInterface dialog) {

						if (Uri.fromFile(new File(selectedImagePath)) != null) {
							getContentResolver().delete(
									Uri.fromFile(new File(selectedImagePath)),
									null, null);

						}
					}
				});

				AlertDialog alert = builder.create();

				alert.show();
			}
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {

		Log.d("h2", "onActivityResult");
		if (resultCode != RESULT_OK)
			finish();

		switch (requestCode) {
		case FROM_CROP:
			Log.d("h2", "FROMFROMCROP");
			if (data != null) {
				Log.d("h2", "fromCrop");
				Bundle extras = data.getExtras();
				cropBitmap = extras.getParcelable("data");

				ComicSurfaceView._croppedBitmap = cropBitmap;
				ComicSurfaceView.isCropped = true;
			} else {
				ComicSurfaceView.isCropped = false;
				Log.d("h2", "NotFromCrop");
			}
			break;
		case SELECT_DEFAULT:

			if (data != null) {
				selectedImagePath = data.getExtras().getString("path");
				rotate = false;
				ComicSurfaceView.setImagePath(selectedImagePath, rotate);
			} else
				finish(); // if user press back button

			break;
		case SELECT_GALLERY:

			if (data != null) {
				Uri selectedImageUri = data.getData();
				selectedImagePath = this.getRealPathFromURI(selectedImageUri);

				rotate = true;
				ComicSurfaceView.setImagePath(selectedImagePath, rotate);
			} else
				finish(); // if user press back button
			break;
		case SELECT_WEB:

			if (data != null) {
				String path = data.getExtras().getString("path");
				selectedImagePath = Environment.getExternalStorageDirectory()
						.getAbsolutePath() + "/dimages/" + path;

				rotate = false;
				ComicSurfaceView.setImagePath(selectedImagePath, rotate);
			} else
				finish(); // if user press back button

			break;
		case SELECT_CAMERA:
			selectedImagePath = this.getRealPathFromURI(this.mImageCaptureUri);

			if (selectedImagePath != null) {
				rotate = true;
				ComicSurfaceView.setImagePath(selectedImagePath, rotate);
			} else
				finish();
			break;
		}
	}

	// get the real path of the image from gallery
	// http://stackoverflow.com/questions/11591825/how-to-get-image-path-just-captured-from-camera
	public String getRealPathFromURI(Uri contentUri) {
		try {
			String[] proj = { MediaStore.Images.Media.DATA };
			Cursor cursor = managedQuery(contentUri, proj, null, null, null);
			int column_index = cursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			return cursor.getString(column_index);
		} catch (Exception e) {
			return contentUri.getPath();
		}
	}

	@Override
	public void onDestroy() {
		ComicSurfaceView.pause();

		ComicSurfaceView = null;
		
		if (cropBitmap != null) {
			cropBitmap.recycle();
		}

		Log.d("h2", "ImageEditor destroyed");

		super.onDestroy();
	}

	@Override
	public void onPause() {
		Log.d("h2", "ImageEditorActivity paused");
		super.onPause();
		ComicSurfaceView.pause();

	}

	// static inner class for saving the bitmap
	private class ExportBitmapToFile extends AsyncTask<Intent, Void, Boolean> {
		private Context mContext;
		private Handler mHandler;
		private Bitmap nBitmap;
		private String pathToSave;

		public ExportBitmapToFile(Context context, Handler handler,
				Bitmap bitmap, String path) {
			mContext = context;
			nBitmap = bitmap;
			mHandler = handler;
			pathToSave = path;
		}

		@Override
		protected Boolean doInBackground(Intent... arg0) {
			// delete temp image, if image comes from default images
			if (isDefault) {
				File f = new File(selectedImagePath);
				f.delete();
			}
			try {
				if (!APP_FILE_PATH.exists()) {
					APP_FILE_PATH.mkdirs();
				}

				File sdCard = Environment.getExternalStorageDirectory();
				File dir = new File(sdCard.getAbsolutePath() + "/dimages");
				dir.mkdirs();

				selectedImagePath = System.currentTimeMillis()
						+ "galleryImg.jpg";
				File file = new File(dir, selectedImagePath);
				selectedImagePath = file.toString();

				final FileOutputStream out = new FileOutputStream(file);
				nBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
				out.flush();
				out.close();
				return true;
			} catch (Exception e) {
				e.printStackTrace();
			}
			// mHandler.post(completeRunnable);
			return false;
		}

		@Override
		protected void onPostExecute(Boolean bool) {
			super.onPostExecute(bool);
			if (bool) {
				mHandler.sendEmptyMessage(1);
			}
		}
	}

}